package it.happyisland.framework.web.render;

import it.happyisland.framework.web.core.Reflection;

import java.lang.reflect.Field;
import java.util.List;


public abstract class Json {
	
	public static Json convert(final Object value){
		if (value == null) {
			return new Json() {
				
				@Override
				public String toJson() {
					return "null";
				}
			};
		}
		if (value.getClass().isArray()) {
			Object[] array = (Object[]) value;
			JsonArray jsonArray = new JsonArray();
			for(Object o: array){
				jsonArray.add(o);
			}
			return jsonArray;
		}
		if (value instanceof Iterable) {
			Iterable<?> iterable = (Iterable<?>) value;
			JsonArray jsonArray = new JsonArray();
			for(Object o: iterable){
				jsonArray.add(o);
			}
			return jsonArray;
		}
		
		if (value instanceof Integer) {
			return new Json() {
				
				@Override
				public String toJson() {
					return Integer.toString((Integer) value);
				}
			};
		}
		if (value instanceof Float) {
			return new Json() {
				
				@Override
				public String toJson() {
					return Float.toString((Float) value);
				}
			};
		}
		if (value instanceof Double) {
			return new Json() {
				
				@Override
				public String toJson() {
					return Double.toString((Double) value);
				}
			};
		}
		if (value instanceof Long) {
			return new Json() {
				
				@Override
				public String toJson() {
					return Long.toString((Long) value);
				}
			};
		}
		if (value instanceof Boolean) {
			return new Json() {
				
				@Override
				public String toJson() {
					return Boolean.toString((Boolean) value);
				}
			};
		}
		if (value instanceof String) {
			return new JsonString((String) value);
		}
		if (value instanceof Json) {
			return (Json) value;
		}
		
		// java bean
		JsonObject object = new JsonObject();
		
		List<Field> fields = Reflection.fields(value.getClass());
		for(Field field: fields){
			field.setAccessible(true);
			Object fieldValue = Reflection.get(value, field);
			if(fieldValue != null) object.put(field.getName(), fieldValue);
		}
		return object;
	}
	
	abstract String toJson();
	
	@Override
	public final String toString() {
		return toJson();
	}
	
}
